package net.hands.common;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
/**
 * 
* 说明:cvs读取流
 * <br>
 * <p>这是一个开源的软件，请在LGPLv3下合法使用、修改或重新发布。</p>
 * @author 陈侃(cknet@126.com, 13910090885)
 *         http://code.google.com/p/simpleframework/
 *         http://www.simpleframework.net
 */
@SuppressWarnings("unchecked")
public class CSVReader {
	/**
	 * 缓存读取
	 */
	private final BufferedReader br;
   /**
    * 还有下一个
    */
	private boolean hasNext = true;
   /**
    * 分隔符
    */
	private final char separator;
   /**
    * 引用符
    */
	private final char quotechar;
   /**
    * 跳行数
    */
	private final int skipLines;
   /**
    * 是否被条行
    */
	private boolean linesSkiped;
   /**
    * 默认分隔符 为,
    */
	public static final char DEFAULT_SEPARATOR = ',';
   /**
    * 默认应用符 为"
    */
	public static final char DEFAULT_QUOTE_CHARACTER = '"';
   /**
    * 默认跳行个数 为0
    */
	public static final int DEFAULT_SKIP_LINES = 0;
   /**
    * 
   * Constructor Method  
   * @update 2012-9-24 上午11:23:58  
   * @param reader 读取流
    */
	public CSVReader(final Reader reader) {
		this(reader, DEFAULT_SEPARATOR);
	}
   /**
    * 
   * Constructor Method  
   * @update 2012-9-24 上午11:24:07  
   * @param reader 读取流
   * @param separator 分隔符
    */
	public CSVReader(final Reader reader, final char separator) {
		this(reader, separator, DEFAULT_QUOTE_CHARACTER);
	}
  /**
   * 
  * Constructor Method  
  * @update 2012-9-24 上午11:24:42  
  * @param reader 读取流
  * @param separator 分隔符
  * @param quotechar 应用符
   */
	public CSVReader(final Reader reader, final char separator, final char quotechar) {
		this(reader, separator, quotechar, DEFAULT_SKIP_LINES);
	}
   /**
    * 
   * Constructor Method  
   * @update 2012-9-24 上午11:25:37  
   * @param reader  读取流
   * @param separator 分隔符
   * @param quotechar  应用符
   * @param line   跳过行数
    */
	public CSVReader(final Reader reader, final char separator, final char quotechar, final int line) {
		this.br = new BufferedReader(reader);
		this.separator = separator;
		this.quotechar = quotechar;
		this.skipLines = line;
	}
   /**
   * 说明:读取所有
   * @return List
   * @throws IOException
   * @update 2012-9-24 上午11:26:17
    */
	@SuppressWarnings("rawtypes")
	public List readAll() throws IOException {
		final List allElements = new ArrayList();
		while (hasNext) {
			final String[] nextLineAsTokens = readNext();
			if (nextLineAsTokens != null) {
				allElements.add(nextLineAsTokens);
			}
		}
		return allElements;
	}
   /**
   * 说明:读取下一行,执行获得行并解析后返回
   * @return String[]
   * @throws IOException
   * @update 2012-9-24 上午11:27:01
    */
	public String[] readNext() throws IOException {
		final String nextLine = getNextLine();
		return hasNext ? parseLine(nextLine) : null;
	}
   /**
   * 说明:获得下一行,skipLines开始读取
   * @return String
   * @throws IOException
   * @update 2012-9-24 上午11:27:28
    */
	private String getNextLine() throws IOException {
		if (!this.linesSkiped) {
			for (int i = 0; i < skipLines; i++) {
				br.readLine();
			}
			this.linesSkiped = true;
		}
		final String nextLine = br.readLine();
		if (nextLine == null) {
			hasNext = false;
		}
		return hasNext ? nextLine : null;
	}
   /**
   * 说明:解析行
   * @param nextLine 字符行
   * @return String[]
   * @throws IOException
   * @update 2012-9-24 上午11:29:26
    */
	@SuppressWarnings("rawtypes")
	private String[] parseLine(String nextLine) throws IOException {
		if (nextLine == null) {
			return null;
		}

		final List tokensOnThisLine = new ArrayList();//字符串用分隔符分开的集合
		StringBuilder sb = new StringBuilder();
		boolean inQuotes = false;
		do {
			if (inQuotes) {
				sb.append("\n");
				nextLine = getNextLine();
				if (nextLine == null) {
					break;
				}
			}
			for (int i = 0; i < nextLine.length(); i++) {
				final char c = nextLine.charAt(i);
				if (c == quotechar) {//如果为引用符
					if (inQuotes && nextLine.length() > (i + 1) && nextLine.charAt(i + 1) == quotechar) {
						sb.append(nextLine.charAt(i + 1));
						i++;
					} else {
						inQuotes = !inQuotes;//第一次用符设置为true,第二次引用符设置为false,如此循环
						if (i > 2 && nextLine.charAt(i - 1) != this.separator
								&& nextLine.length() > (i + 1) && nextLine.charAt(i + 1) != this.separator) {
							sb.append(c);
						}
					}
				} else if (c == separator && !inQuotes) {//是分隔符 并引用符为false
					tokensOnThisLine.add(sb.toString());//字符串用分隔符分开的集合
					sb = new StringBuilder(); // 新启动一个字符缓存
				} else {//如果不是添加到字符缓存中
					sb.append(c);
				}
			}
		} while (inQuotes);
		tokensOnThisLine.add(sb.toString());
		return (String[]) tokensOnThisLine.toArray(new String[0]);
	}
   /**
   * 说明:关闭
   * @throws IOException
   * @update 2012-9-24 上午11:40:57
    */
	public void close() throws IOException {
		br.close();
	}
}
